home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / ghost / gs403src_png.lha / gs4.03 / libpng / pngrtran.c < prev    next >
C/C++ Source or Header  |  1996-06-05  |  97KB  |  2,922 lines

  1.  
  2. /* pngrtran.c - transforms the data in a row for png readers
  3.  
  4.    libpng 1.0 beta 3 - version 0.89
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    May 25, 1996
  8.    */
  9.  
  10. #define PNG_INTERNAL
  11. #include "png.h"
  12.  
  13. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  14. /* handle alpha and tRNS via a background color */
  15. void
  16. png_set_background(png_structp png_ptr,
  17.    png_color_16p background_color, int background_gamma_code,
  18.    int need_expand, double background_gamma)
  19. {
  20.    png_ptr->transformations |= PNG_BACKGROUND;
  21.    png_memcpy(&(png_ptr->background), background_color,
  22.       sizeof(png_color_16));
  23.    png_ptr->background_gamma = (float)background_gamma;
  24.    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
  25.    png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
  26. }
  27. #endif
  28.  
  29. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  30. /* strip 16 bit depth files to 8 bit depth */
  31. void
  32. png_set_strip_16(png_structp png_ptr)
  33. {
  34.    png_ptr->transformations |= PNG_16_TO_8;
  35. }
  36. #endif
  37.  
  38. #if defined(PNG_READ_DITHER_SUPPORTED)
  39. /* dither file to 8 bit.  Supply a palette, the current number
  40.    of elements in the palette, the maximum number of elements
  41.    allowed, and a histogram, if possible.  If the current number
  42.    is greater then the maximum number, the palette will be
  43.    modified to fit in the maximum number */
  44.  
  45.  
  46. typedef struct png_dsort_struct
  47. {
  48.    struct png_dsort_struct FAR * next;
  49.    png_byte left;
  50.    png_byte right;
  51. } png_dsort;
  52. typedef png_dsort FAR *       png_dsortp;
  53. typedef png_dsort FAR * FAR * png_dsortpp;
  54.  
  55. void
  56. png_set_dither(png_structp png_ptr, png_colorp palette,
  57.    int num_palette, int maximum_colors, png_uint_16p histogram,
  58.    int full_dither)
  59. {
  60.    png_ptr->transformations |= PNG_DITHER;
  61.  
  62.    if (!full_dither)
  63.    {
  64.       int i;
  65.  
  66.       png_ptr->dither_index = (png_bytep)png_large_malloc(png_ptr,
  67.          num_palette * sizeof (png_byte));
  68.       for (i = 0; i < num_palette; i++)
  69.          png_ptr->dither_index[i] = (png_byte)i;
  70.    }
  71.  
  72.    if (num_palette > maximum_colors)
  73.    {
  74.       if (histogram)
  75.       {
  76.          /* this is easy enough, just throw out the least used colors.
  77.             perhaps not the best solution, but good enough */
  78.  
  79.          int i;
  80.          png_bytep sort;
  81.  
  82.          /* initialize an array to sort colors */
  83.          sort = (png_bytep)png_large_malloc(png_ptr, num_palette * sizeof (png_byte));
  84.  
  85.          /* initialize the sort array */
  86.          for (i = 0; i < num_palette; i++)
  87.             sort[i] = (png_byte)i;
  88.  
  89.          /* find the least used palette entries by starting a
  90.             bubble sort, and running it until we have sorted
  91.             out enough colors.  Note that we don't care about
  92.             sorting all the colors, just finding which are
  93.             least used. */
  94.  
  95.          for (i = num_palette - 1; i >= maximum_colors; i--)
  96.          {
  97.             int done; /* to stop early if the list is pre-sorted */
  98.             int j;
  99.  
  100.             done = 1;
  101.             for (j = 0; j < i; j++)
  102.             {
  103.                if (histogram[sort[j]] < histogram[sort[j + 1]])
  104.                {
  105.                   png_byte t;
  106.  
  107.                   t = sort[j];
  108.                   sort[j] = sort[j + 1];
  109.                   sort[j + 1] = t;
  110.                   done = 0;
  111.                }
  112.             }
  113.             if (done)
  114.                break;
  115.          }
  116.  
  117.          /* swap the palette around, and set up a table, if necessary */
  118.          if (full_dither)
  119.          {
  120.             int j;
  121.  
  122.             /* put all the useful colors within the max, but don't
  123.                move the others */
  124.             j = num_palette;
  125.             for (i = 0; i < maximum_colors; i++)
  126.             {
  127.                if (sort[i] >= maximum_colors)
  128.                {
  129.                   do
  130.                      j--;
  131.                   while (sort[j] >= maximum_colors);
  132.                   palette[i] = palette[j];
  133.                }
  134.             }
  135.          }
  136.          else
  137.          {
  138.             int j;
  139.  
  140.             /* move all the used colors inside the max limit, and
  141.                develop a translation table */
  142.             j = num_palette;
  143.             for (i = 0; i < maximum_colors; i++)
  144.             {
  145.                /* only move the colors we need to */
  146.                if (sort[i] >= maximum_colors)
  147.                {
  148.                   png_color tmp_color;
  149.  
  150.                   do
  151.                      j--;
  152.                   while (sort[j] >= maximum_colors);
  153.  
  154.                   tmp_color = palette[j];
  155.                   palette[j] = palette[i];
  156.                   palette[i] = tmp_color;
  157.                   /* indicate where the color went */
  158.                   png_ptr->dither_index[j] = (png_byte)i;
  159.                   png_ptr->dither_index[i] = (png_byte)j;
  160.                }
  161.             }
  162.             /* find closest color for those colors we are not
  163.                using */
  164.             for (i = 0; i < num_palette; i++)
  165.             {
  166.                if (png_ptr->dither_index[i] >= maximum_colors)
  167.                {
  168.                   int min_d, j, min_j, index;
  169.  
  170.                   /* find the closest color to one we threw out */
  171.                   index = png_ptr->dither_index[i];
  172.                   min_d = PNG_COLOR_DIST(palette[index],
  173.                         palette[0]);
  174.                   min_j = 0;
  175.                   for (j = 1; j < maximum_colors; j++)
  176.                   {
  177.                      int d;
  178.  
  179.                      d = PNG_COLOR_DIST(palette[index],
  180.                         palette[j]);
  181.  
  182.                      if (d < min_d)
  183.                      {
  184.                         min_d = d;
  185.                         min_j = j;
  186.                      }
  187.                   }
  188.                   /* point to closest color */
  189.                   png_ptr->dither_index[i] = (png_byte)min_j;
  190.                }
  191.             }
  192.          }
  193.          png_large_free(png_ptr, sort);
  194.       }
  195.       else
  196.       {
  197.          /* this is much harder to do simply (and quickly).  Perhaps
  198.             we need to go through a median cut routine, but those
  199.             don't always behave themselves with only a few colors
  200.             as input.  So we will just find the closest two colors,
  201.             and throw out one of them (chosen somewhat randomly).
  202.             */
  203.          int i;
  204.          int max_d;
  205.          int num_new_palette;
  206.          png_dsortpp hash;
  207.          png_bytep index_to_palette;
  208.             /* where the original index currently is in the palette */
  209.          png_bytep palette_to_index;
  210.             /* which original index points to this palette color */
  211.  
  212.          /* initialize palette index arrays */
  213.          index_to_palette = (png_bytep)png_large_malloc(png_ptr,
  214.             num_palette * sizeof (png_byte));
  215.          palette_to_index = (png_bytep)png_large_malloc(png_ptr,
  216.             num_palette * sizeof (png_byte));
  217.  
  218.          /* initialize the sort array */
  219.          for (i = 0; i < num_palette; i++)
  220.          {
  221.             index_to_palette[i] = (png_byte)i;
  222.             palette_to_index[i] = (png_byte)i;
  223.          }
  224.  
  225.          hash = (png_dsortpp)png_large_malloc(png_ptr, 769 * sizeof (png_dsortp));
  226.          for (i = 0; i < 769; i++)
  227.             hash[i] = (png_dsortp)0;
  228. /*         png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
  229.  
  230.          num_new_palette = num_palette;
  231.  
  232.          /* initial wild guess at how far apart the farthest pixel
  233.             pair we will be eliminating will be.  Larger
  234.             numbers mean more areas will be allocated, Smaller
  235.             numbers run the risk of not saving enough data, and
  236.             having to do this all over again.
  237.  
  238.             I have not done extensive checking on this number.
  239.             */
  240.          max_d = 96;
  241.  
  242.          while (num_new_palette > maximum_colors)
  243.          {
  244.             for (i = 0; i < num_new_palette - 1; i++)
  245.             {
  246.                int j;
  247.  
  248.                for (j = i + 1; j < num_new_palette; j++)
  249.                {
  250.                   int d;
  251.  
  252.                   d = PNG_COLOR_DIST(palette[i], palette[j]);
  253.  
  254.                   if (d <= max_d)
  255.                   {
  256.                      png_dsortp t;
  257.  
  258.                      t = png_large_malloc(png_ptr, sizeof (png_dsort));
  259.                      t->next = hash[d];
  260.                      t->left = (png_byte)i;
  261.                      t->right = (png_byte)j;
  262.                      hash[d] = t;
  263.                   }
  264.                }
  265.             }
  266.  
  267.             for (i = 0; i <= max_d; i++)
  268.             {
  269.                if (hash[i])
  270.                {
  271.                   png_dsortp p;
  272.  
  273.                   for (p = hash[i]; p; p = p->next)
  274.                   {
  275.                      if (index_to_palette[p->left] < num_new_palette &&
  276.                         index_to_palette[p->right] < num_new_palette)
  277.                      {
  278.                         int j, next_j;
  279.  
  280.                         if (num_new_palette & 1)
  281.                         {
  282.                            j = p->left;
  283.                            next_j = p->right;
  284.                         }
  285.                         else
  286.                         {
  287.                            j = p->right;
  288.                            next_j = p->left;
  289.                         }
  290.  
  291.                         num_new_palette--;
  292.                         palette[index_to_palette[j]] =
  293.                            palette[num_new_palette];
  294.                         if (!full_dither)
  295.                         {
  296.                            int k;
  297.  
  298.                            for (k = 0; k < num_palette; k++)
  299.                            {
  300.                               if (png_ptr->dither_index[k] ==
  301.                                  index_to_palette[j])
  302.                                  png_ptr->dither_index[k] =
  303.                                     index_to_palette[next_j];
  304.                               if (png_ptr->dither_index[k] ==
  305.                                  num_new_palette)
  306.                                  png_ptr->dither_index[k] =
  307.                                     index_to_palette[j];
  308.                            }
  309.                         }
  310.  
  311.                         index_to_palette[palette_to_index[num_new_palette]] =
  312.                            index_to_palette[j];
  313.                         palette_to_index[index_to_palette[j]] =
  314.                            palette_to_index[num_new_palette];
  315.  
  316.                         index_to_palette[j] = (png_byte)num_new_palette;
  317.                         palette_to_index[num_new_palette] = (png_byte)j;
  318.                      }
  319.                      if (num_new_palette <= maximum_colors)
  320.                         break;
  321.                   }
  322.                   if (num_new_palette <= maximum_colors)
  323.                      break;
  324.                }
  325.             }
  326.  
  327.             for (i = 0; i < 769; i++)
  328.             {
  329.                if (hash[i])
  330.                {
  331.                   png_dsortp p;
  332.  
  333.                   p = hash[i];
  334.                   while (p)
  335.                   {
  336.                      png_dsortp t;
  337.  
  338.                      t = p->next;
  339.                      png_large_free(png_ptr, p);
  340.                      p = t;
  341.                   }
  342.                }
  343.                hash[i] = 0;
  344.             }
  345.             max_d += 96;
  346.          }
  347.          png_large_free(png_ptr, hash);
  348.          png_large_free(png_ptr, palette_to_index);
  349.          png_large_free(png_ptr, index_to_palette);
  350.       }
  351.       num_palette = maximum_colors;
  352.    }
  353.    if (!(png_ptr->palette))
  354.    {
  355.       png_ptr->palette = palette;
  356.    }
  357.    png_ptr->num_palette = (png_uint_16)num_palette;
  358.  
  359.    if (full_dither)
  360.    {
  361.       int i;
  362.       int total_bits, num_red, num_green, num_blue;
  363.       png_uint_32 num_entries;
  364.       png_bytep distance;
  365.  
  366.       total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
  367.          PNG_DITHER_BLUE_BITS;
  368.  
  369.       num_red = (1 << PNG_DITHER_RED_BITS);
  370.       num_green = (1 << PNG_DITHER_GREEN_BITS);
  371.       num_blue = (1 << PNG_DITHER_BLUE_BITS);
  372.       num_entries = ((png_uint_32)1 << total_bits);
  373.  
  374.       png_ptr->palette_lookup = (png_bytep )png_large_malloc(png_ptr,
  375.          (png_size_t)num_entries * sizeof (png_byte));
  376.  
  377.       png_memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte));
  378.  
  379.       distance = (png_bytep )png_large_malloc(png_ptr,
  380.          (png_size_t)num_entries * sizeof (png_byte));
  381.  
  382.       png_memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte));
  383.  
  384.       for (i = 0; i < num_palette; i++)
  385.       {
  386.          int r, g, b, ir, ig, ib;
  387.  
  388.          r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
  389.          g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
  390.          b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
  391.  
  392.          for (ir = 0; ir < num_red; ir++)
  393.          {
  394.             int dr, index_r;
  395.  
  396.             dr = abs(ir - r);
  397.             index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
  398.             for (ig = 0; ig < num_green; ig++)
  399.             {
  400.                int dg, dt, dm, index_g;
  401.  
  402.                dg = abs(ig - g);
  403.                dt = dr + dg;
  404.                dm = ((dr > dg) ? dr : dg);
  405.                index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
  406.                for (ib = 0; ib < num_blue; ib++)
  407.                {
  408.                   int index, db, dmax, d;
  409.  
  410.                   index = index_g | ib;
  411.                   db = abs(ib - b);
  412.                   dmax = ((dm > db) ? dm : db);
  413.                   d = dmax + dt + db;
  414.  
  415.                   if (d < distance[index])
  416.                   {
  417.                      distance[index] = (png_byte)d;
  418.                      png_ptr->palette_lookup[index] = (png_byte)i;
  419.                   }
  420.                }
  421.             }
  422.          }
  423.       }
  424.  
  425.       png_large_free(png_ptr, distance);
  426.    }
  427. }
  428. #endif
  429.  
  430. #if defined(PNG_READ_GAMMA_SUPPORTED)
  431. /* transform the image from the file_gamma to the screen_gamma */
  432. void
  433. png_set_gamma(png_structp png_ptr, double screen_gamma,
  434.    double file_gamma)
  435. {
  436.    png_ptr->transformations |= PNG_GAMMA;
  437.    png_ptr->gamma = (float)file_gamma;
  438.    png_ptr->display_gamma = (float)screen_gamma;
  439. }
  440. #endif
  441.  
  442. #if defined(PNG_READ_EXPAND_SUPPORTED)
  443. /* expand paletted images to rgb, expand grayscale images of
  444.    less then 8 bit depth to 8 bit depth, and expand tRNS chunks
  445.    to alpha channels */
  446. void
  447. png_set_expand(png_structp png_ptr)
  448. {
  449.    png_ptr->transformations |= PNG_EXPAND;
  450. }
  451. #endif
  452.  
  453. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  454. void
  455. png_set_gray_to_rgb(png_structp png_ptr)
  456. {
  457.    png_ptr->transformations |= PNG_GRAY_TO_RGB;
  458. }
  459. #endif
  460.  
  461. /* initialize everything needed for the read.  This includes modifying
  462.    the palette */
  463. void
  464. png_init_read_transformations(png_structp png_ptr)
  465. {
  466.    int color_type;
  467.  
  468.    color_type = png_ptr->color_type;
  469.  
  470. #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
  471.    if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
  472.    {
  473.       if (color_type == PNG_COLOR_TYPE_GRAY)
  474.       {
  475.          /* expand background chunk. */
  476.          switch (png_ptr->bit_depth)
  477.          {
  478.             case 1:
  479.                png_ptr->background.gray *= (png_uint_16)0xff;
  480.                png_ptr->background.red = png_ptr->background.green =
  481.                png_ptr->background.blue = png_ptr->background.gray;
  482.                break;
  483.             case 2:
  484.                png_ptr->background.gray *= (png_uint_16)0x55;
  485.                png_ptr->background.red = png_ptr->background.green =
  486.                png_ptr->background.blue = png_ptr->background.gray;
  487.                break;
  488.             case 4:
  489.                png_ptr->background.gray *= (png_uint_16)0x11;
  490.                png_ptr->background.red = png_ptr->background.green =
  491.                png_ptr->background.blue = png_ptr->background.gray;
  492.                break;
  493.             case 8:
  494.             case 16:
  495.                png_ptr->background.red = png_ptr->background.green =
  496.                png_ptr->background.blue = png_ptr->background.gray;
  497.                break;
  498.          }
  499.       }
  500.       else if (color_type == PNG_COLOR_TYPE_PALETTE)
  501.       {
  502.          png_ptr->background.red   =
  503.             png_ptr->palette[png_ptr->background.index].red;
  504.          png_ptr->background.green =
  505.             png_ptr->palette[png_ptr->background.index].green;
  506.          png_ptr->background.blue  =
  507.             png_ptr->palette[png_ptr->background.index].blue;
  508.       }
  509.    }
  510. #endif
  511.  
  512. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  513.    png_ptr->background_1 = png_ptr->background;
  514. #endif
  515. #if defined(PNG_READ_GAMMA_SUPPORTED)
  516.    if (png_ptr->transformations & PNG_GAMMA)
  517.    {
  518.       png_build_gamma_table(png_ptr);
  519. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  520.       if (png_ptr->transformations & PNG_BACKGROUND)
  521.       {
  522.          if (color_type == PNG_COLOR_TYPE_PALETTE)
  523.          {
  524.             int num_palette, i;
  525.             png_color back, back_1;
  526.             png_colorp palette;
  527.  
  528.             palette = png_ptr->palette;
  529.             num_palette = png_ptr->num_palette;
  530.  
  531.             back.red = png_ptr->gamma_table[png_ptr->background.red];
  532.             back.green = png_ptr->gamma_table[png_ptr->background.green];
  533.             back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  534.  
  535.             back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  536.             back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  537.             back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  538.  
  539.             for (i = 0; i < num_palette; i++)
  540.             {
  541.                if (i < (int)png_ptr->num_trans)
  542.                {
  543.                   if (png_ptr->trans[i] == 0)
  544.                   {
  545.                      palette[i] = back;
  546.                   }
  547.                   else if (png_ptr->trans[i] != 0xff)
  548.                   {
  549.                      int v, w;
  550.  
  551.                      v = png_ptr->gamma_to_1[palette[i].red];
  552.                      w = (int)(((png_uint_32)(v) *
  553.                         (png_uint_32)(png_ptr->trans[i]) +
  554.                         (png_uint_32)(back_1.red) *
  555.                         (png_uint_32)(255 - png_ptr->trans[i]) +
  556.                         127) / 255);
  557.                      palette[i].red = png_ptr->gamma_from_1[w];
  558.  
  559.                      v = png_ptr->gamma_to_1[palette[i].green];
  560.                      w = (int)(((png_uint_32)(v) *
  561.                         (png_uint_32)(png_ptr->trans[i]) +
  562.                         (png_uint_32)(back_1.green) *
  563.                         (png_uint_32)(255 - png_ptr->trans[i]) +
  564.                         127) / 255);
  565.                      palette[i].green = png_ptr->gamma_from_1[w];
  566.  
  567.                      v = png_ptr->gamma_to_1[palette[i].blue];
  568.                      w = (int)(((png_uint_32)(v) *
  569.                         (png_uint_32)(png_ptr->trans[i]) +
  570.                         (png_uint_32)(back_1.blue) *
  571.                         (png_uint_32)(255 - png_ptr->trans[i]) +
  572.                         127) / 255);
  573.                      palette[i].blue = png_ptr->gamma_from_1[w];
  574.                   }
  575.                }
  576.                else
  577.                {
  578.                   palette[i].red = png_ptr->gamma_table[palette[i].red];
  579.                   palette[i].green = png_ptr->gamma_table[palette[i].green];
  580.                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  581.                }
  582.             }
  583.          }
  584.          else if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)
  585.          {
  586.             double g, gs, m;
  587.  
  588.             m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
  589.             g = 1.0;
  590.             gs = 1.0;
  591.  
  592.             switch (png_ptr->background_gamma_type)
  593.             {
  594.                case PNG_BACKGROUND_GAMMA_SCREEN:
  595.                   g = (png_ptr->display_gamma);
  596.                   gs = 1.0;
  597.                   break;
  598.                case PNG_BACKGROUND_GAMMA_FILE:
  599.                   g = 1.0 / (png_ptr->gamma);
  600.                   gs = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  601.                   break;
  602.                case PNG_BACKGROUND_GAMMA_UNIQUE:
  603.                   g = 1.0 / (png_ptr->background_gamma);
  604.                   gs = 1.0 / (png_ptr->background_gamma *
  605.                      png_ptr->display_gamma);
  606.                   break;
  607.             }
  608.  
  609.             if (color_type & PNG_COLOR_MASK_COLOR)
  610.             {
  611.                png_ptr->background_1.red = (png_uint_16)(pow(
  612.                   (double)png_ptr->background.red / m, g) * m + .5);
  613.                png_ptr->background_1.green = (png_uint_16)(pow(
  614.                   (double)png_ptr->background.green / m, g) * m + .5);
  615.                png_ptr->background_1.blue = (png_uint_16)(pow(
  616.                   (double)png_ptr->background.blue / m, g) * m + .5);
  617.                png_ptr->background.red = (png_uint_16)(pow(
  618.                   (double)png_ptr->background.red / m, gs) * m + .5);
  619.                png_ptr->background.green = (png_uint_16)(pow(
  620.                   (double)png_ptr->background.green / m, gs) * m + .5);
  621.                png_ptr->background.blue = (png_uint_16)(pow(
  622.                   (double)png_ptr->background.blue / m, gs) * m + .5);
  623.             }
  624.             else
  625.             {
  626.                png_ptr->background_1.gray = (png_uint_16)(pow(
  627.                   (double)png_ptr->background.gray / m, g) * m + .5);
  628.                png_ptr->background.gray = (png_uint_16)(pow(
  629.                   (double)png_ptr->background.gray / m, gs) * m + .5);
  630.             }
  631.          }
  632.       }
  633.       else
  634. #endif
  635.       if (color_type == PNG_COLOR_TYPE_PALETTE)
  636.       {
  637.          int num_palette, i;
  638.          png_colorp palette;
  639.  
  640.          palette = png_ptr->palette;
  641.          num_palette = png_ptr->num_palette;
  642.  
  643.          for (i = 0; i < num_palette; i++)
  644.          {
  645.             palette[i].red = png_ptr->gamma_table[palette[i].red];
  646.             palette[i].green = png_ptr->gamma_table[palette[i].green];
  647.             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  648.          }
  649.       }
  650.    }
  651. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  652.    else
  653. #endif
  654. #endif
  655. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  656.    if (png_ptr->transformations & PNG_BACKGROUND &&
  657.        color_type == PNG_COLOR_TYPE_PALETTE)
  658.    {
  659.       int i;
  660.       png_color back;
  661.       png_colorp palette;
  662.  
  663.       palette = png_ptr->palette;
  664.       back.red   = (png_byte)png_ptr->background.red;
  665.       back.green = (png_byte)png_ptr->background.green;
  666.       back.blue  = (png_byte)png_ptr->background.blue;
  667.  
  668.       for (i = 0; i < png_ptr->num_trans; i++)
  669.       {
  670.          if (png_ptr->trans[i] == 0)
  671.          {
  672.             palette[i] = back;
  673.          }
  674.          else if (png_ptr->trans[i] != 0xff)
  675.          {
  676.             palette[i].red = (png_byte)((
  677.                (png_uint_32)(palette[i].red) *
  678.                (png_uint_32)(png_ptr->trans[i]) +
  679.                (png_uint_32)(back.red) *
  680.                (png_uint_32)(255 - png_ptr->trans[i]) +
  681.                127) / 255);
  682.             palette[i].green = (png_byte)((
  683.                (png_uint_32)(palette[i].green) *
  684.                (png_uint_32)(png_ptr->trans[i]) +
  685.                (png_uint_32)(back.green) *
  686.                (png_uint_32)(255 - png_ptr->trans[i]) +
  687.                127) / 255);
  688.             palette[i].blue = (png_byte)((
  689.                (png_uint_32)(palette[i].blue) *
  690.                (png_uint_32)(png_ptr->trans[i]) +
  691.                (png_uint_32)(back.blue) *
  692.                (png_uint_32)(255 - png_ptr->trans[i]) +
  693.                127) / 255);
  694.          }
  695.       }
  696.    }
  697. #endif
  698.  
  699. #if defined(PNG_READ_SHIFT_SUPPORTED)
  700.    if ((png_ptr->transformations & PNG_SHIFT) &&
  701.       color_type == PNG_COLOR_TYPE_PALETTE)
  702.    {
  703.       png_uint_16 i;
  704.       int sr, sg, sb;
  705.  
  706.       sr = 8 - png_ptr->sig_bit.red;
  707.       if (sr < 0 || sr > 8)
  708.          sr = 0;
  709.       sg = 8 - png_ptr->sig_bit.green;
  710.       if (sg < 0 || sg > 8)
  711.          sg = 0;
  712.       sb = 8 - png_ptr->sig_bit.blue;
  713.       if (sb < 0 || sb > 8)
  714.          sb = 0;
  715.       for (i = 0; i < png_ptr->num_palette; i++)
  716.       {
  717.          png_ptr->palette[i].red >>= sr;
  718.          png_ptr->palette[i].green >>= sg;
  719.          png_ptr->palette[i].blue >>= sb;
  720.       }
  721.    }
  722. #endif
  723. }
  724.  
  725. /* modify the info structure to reflect the transformations.  The
  726.    info should be updated so a png file could be written with it,
  727.    assuming the transformations result in valid png data */
  728. void
  729. png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
  730. {
  731. #if defined(PNG_READ_EXPAND_SUPPORTED)
  732.    if ((png_ptr->transformations & PNG_EXPAND) &&
  733.       info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  734.    {
  735.       if (png_ptr->num_trans)
  736.          info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  737.       else
  738.          info_ptr->color_type = PNG_COLOR_TYPE_RGB;
  739.       info_ptr->bit_depth = 8;
  740.       info_ptr->num_trans = 0;
  741.    }
  742.    else if (png_ptr->transformations & PNG_EXPAND)
  743.    {
  744.       if (png_ptr->num_trans)
  745.          info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  746.       if (info_ptr->bit_depth < 8)
  747.          info_ptr->bit_depth = 8;
  748.       info_ptr->num_trans = 0;
  749.    }
  750. #endif
  751.  
  752. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  753.    if (png_ptr->transformations & PNG_BACKGROUND)
  754.    {
  755.       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  756.       info_ptr->num_trans = 0;
  757.       info_ptr->background = png_ptr->background;
  758.    }
  759. #endif
  760.  
  761. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  762.    if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
  763.       info_ptr->bit_depth = 8;
  764. #endif
  765.  
  766. #if defined(PNG_READ_DITHER_SUPPORTED)
  767.    if (png_ptr->transformations & PNG_DITHER)
  768.    {
  769.       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  770.          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
  771.          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
  772.       {
  773.          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
  774.       }
  775.    }
  776. #endif
  777.  
  778. #if defined(PNG_READ_PACK_SUPPORTED)
  779.    if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8)
  780.       info_ptr->bit_depth = 8;
  781. #endif
  782.  
  783. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  784.    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  785.       !(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
  786.       info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  787. #endif
  788.    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  789.       info_ptr->channels = 1;
  790.    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  791.       info_ptr->channels = 3;
  792.    else
  793.       info_ptr->channels = 1;
  794.    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  795.       info_ptr->channels++;
  796.    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
  797.       info_ptr->bit_depth);
  798.    info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
  799. }
  800.  
  801. /* transform the row.  The order of transformations is significant,
  802.    and is very touchy.  If you add a transformation, take care to
  803.    decide how it fits in with the other transformations here */
  804. void
  805. png_do_read_transformations(png_structp png_ptr)
  806. {
  807. #if defined(PNG_READ_EXPAND_SUPPORTED)
  808.    if ((png_ptr->transformations & PNG_EXPAND) &&
  809.       png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
  810.    {
  811.       png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
  812.          png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
  813.    }
  814.    else if (png_ptr->transformations & PNG_EXPAND)
  815.    {
  816.       if (png_ptr->num_trans)
  817.          png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  818.             &(png_ptr->trans_values));
  819.       else
  820.          png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  821.             NULL);
  822.    }
  823. #endif
  824.  
  825. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  826.    if (png_ptr->transformations & PNG_BACKGROUND)
  827.       png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
  828.          &(png_ptr->trans_values), &(png_ptr->background),
  829.          &(png_ptr->background_1),
  830.          png_ptr->gamma_table, png_ptr->gamma_from_1,
  831.          png_ptr->gamma_to_1, png_ptr->gamma_16_table,
  832.          png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
  833.          png_ptr->gamma_shift);
  834. #endif
  835.  
  836. #if defined(PNG_READ_GAMMA_SUPPORTED)
  837.    if ((png_ptr->transformations & PNG_GAMMA) &&
  838.       !(png_ptr->transformations & PNG_BACKGROUND))
  839.       png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
  840.          png_ptr->gamma_table, png_ptr->gamma_16_table,
  841.          png_ptr->gamma_shift);
  842. #endif
  843.  
  844. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  845.    if (png_ptr->transformations & PNG_16_TO_8)
  846.       png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
  847. #endif
  848.  
  849. #if defined(PNG_READ_DITHER_SUPPORTED)
  850.    if (png_ptr->transformations & PNG_DITHER)
  851.    {
  852.       png_do_dither((png_row_infop)&(png_ptr->row_info), 
  853.          png_ptr->row_buf + 1,
  854.          png_ptr->palette_lookup,
  855.          png_ptr->dither_index);
  856.    }      
  857. #endif
  858.  
  859. #if defined(PNG_READ_INVERT_SUPPORTED)
  860.    if (png_ptr->transformations & PNG_INVERT_MONO)
  861.       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  862. #endif
  863.  
  864. #if defined(PNG_READ_SHIFT_SUPPORTED)
  865.    if (png_ptr->transformations & PNG_SHIFT)
  866.       png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  867.          &(png_ptr->shift));
  868. #endif
  869.  
  870. #if defined(PNG_READ_PACK_SUPPORTED)
  871.    if (png_ptr->transformations & PNG_PACK)
  872.       png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
  873. #endif
  874.  
  875. #if defined(PNG_READ_BGR_SUPPORTED)
  876.    if (png_ptr->transformations & PNG_BGR)
  877.       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  878. #endif
  879.  
  880. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  881.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  882.       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  883. #endif
  884.  
  885. #if defined(PNG_READ_SWAP_SUPPORTED)
  886.    if (png_ptr->transformations & PNG_SWAP_BYTES)
  887.       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  888. #endif
  889.  
  890. #if defined(PNG_READ_FILLER_SUPPORTED)
  891.    if (png_ptr->transformations & PNG_FILLER)
  892.       png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  893.          png_ptr->filler, png_ptr->flags);
  894. #endif
  895. }
  896.  
  897. #if defined(PNG_READ_PACK_SUPPORTED)
  898. /* unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
  899.    without changing the actual values.  Thus, if you had a row with
  900.    a bit depth of 1, you would end up with bytes that only contained
  901.    the numbers 0 or 1.  If you would rather they contain 0 and 255, use
  902.    png_do_shift() after this. */
  903. void
  904. png_do_unpack(png_row_infop row_info, png_bytep row)
  905. {
  906.    int shift;
  907.    png_bytep sp, dp;
  908.    png_uint_32 i;
  909.    
  910.    if (row && row_info && row_info->bit_depth < 8)
  911.    {
  912.       switch (row_info->bit_depth)
  913.       {
  914.          case 1:
  915.          {
  916.             sp = row + (png_size_t)((row_info->width - 1) >> 3);
  917.             dp = row + (png_size_t)row_info->width - 1;
  918.             shift = 7 - (int)((row_info->width + 7) & 7);
  919.             for (i = 0; i < row_info->width; i++)
  920.             {
  921.                *dp = (png_byte)((*sp >> shift) & 0x1);
  922.                if (shift == 7)
  923.                {
  924.                   shift = 0;
  925.                   sp--;
  926.                }
  927.                else
  928.                   shift++;
  929.  
  930.                dp--;
  931.             }
  932.             break;
  933.          }
  934.          case 2:
  935.          {
  936.  
  937.             sp = row + (png_size_t)((row_info->width - 1) >> 2);
  938.             dp = row + (png_size_t)row_info->width - 1;
  939.             shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  940.             for (i = 0; i < row_info->width; i++)
  941.             {
  942.                *dp = (png_byte)((*sp >> shift) & 0x3);
  943.                if (shift == 6)
  944.                {
  945.                   shift = 0;
  946.                   sp--;
  947.                }
  948.                else
  949.                   shift += 2;
  950.  
  951.                dp--;
  952.             }
  953.             break;
  954.          }
  955.          case 4:
  956.          {
  957.             sp = row + (png_size_t)((row_info->width - 1) >> 1);
  958.             dp = row + (png_size_t)row_info->width - 1;
  959.             shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  960.             for (i = 0; i < row_info->width; i++)
  961.             {
  962.                *dp = (png_byte)((*sp >> shift) & 0xf);
  963.                if (shift == 4)
  964.                {
  965.                   shift = 0;
  966.                   sp--;
  967.                }
  968.                else
  969.                   shift = 4;
  970.  
  971.                dp--;
  972.             }
  973.             break;
  974.          }
  975.       }
  976.       row_info->bit_depth = 8;
  977.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  978.       row_info->rowbytes = row_info->width * row_info->channels;
  979.    }
  980. }
  981. #endif
  982.  
  983. #if defined(PNG_READ_SHIFT_SUPPORTED)
  984. /* reverse the effects of png_do_shift.  This routine merely shifts the
  985.    pixels back to their significant bits values.  Thus, if you have
  986.    a row of bit depth 8, but only 5 are significant, this will shift
  987.    the values back to 0 through 31 */
  988. void
  989. png_do_unshift(png_row_infop row_info, png_bytep row,
  990.    png_color_8p sig_bits)
  991. {
  992.    png_bytep bp;
  993.    png_uint_16 value;
  994.    png_uint_32 i;
  995.    if (row && row_info && sig_bits &&
  996.       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  997.    {
  998.       int shift[4];
  999.       int channels;
  1000.  
  1001.       channels = 0;
  1002.       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
  1003.       {
  1004.          shift[channels++] = row_info->bit_depth - sig_bits->red;
  1005.          shift[channels++] = row_info->bit_depth - sig_bits->green;
  1006.          shift[channels++] = row_info->bit_depth - sig_bits->blue;
  1007.       }
  1008.       else
  1009.       {
  1010.          shift[channels++] = row_info->bit_depth - sig_bits->gray;
  1011.       }
  1012.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  1013.       {
  1014.          shift[channels++] = row_info->bit_depth - sig_bits->alpha;
  1015.       }
  1016.  
  1017.       value = 0;
  1018.  
  1019.       for (i = 0; i < channels; i++)
  1020.       {
  1021.          if (shift[(png_size_t)i] <= 0)
  1022.             shift[(png_size_t)i] = 0;
  1023.          else
  1024.             value = 1;
  1025.       }
  1026.  
  1027.       if (!value)
  1028.          return;
  1029.  
  1030.       switch (row_info->bit_depth)
  1031.       {
  1032.          case 2:
  1033.          {
  1034.             for (bp = row, i = 0;
  1035.                i < row_info->rowbytes;
  1036.                i++, bp++)
  1037.             {
  1038.                *bp >>= 1;
  1039.                *bp &= 0x55;
  1040.             }
  1041.             break;
  1042.          }
  1043.          case 4:
  1044.          {
  1045.             png_byte  mask;
  1046.             mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
  1047.                (png_byte)((int)0xf >> shift[0]);
  1048.             for (bp = row, i = 0;
  1049.                i < row_info->rowbytes;
  1050.                i++, bp++)
  1051.             {
  1052.                *bp >>= shift[0];
  1053.                *bp &= mask;
  1054.             }
  1055.             break;
  1056.          }
  1057.          case 8:
  1058.          {
  1059.             for (bp = row, i = 0;
  1060.                i < row_info->width; i++)
  1061.             {
  1062.                int c;
  1063.  
  1064.                for (c = 0; c < row_info->channels; c++, bp++)
  1065.                {
  1066.                   *bp >>= shift[c];
  1067.                }
  1068.             }
  1069.             break;
  1070.          }
  1071.          case 16:
  1072.          {
  1073.             for (bp = row, i = 0;
  1074.                i < row_info->width; i++)
  1075.             {
  1076.                int c;
  1077.  
  1078.                for (c = 0; c < row_info->channels; c++, bp += 2)
  1079.                {
  1080.                   value = (png_uint_16)((*bp << 8) + *(bp + 1));
  1081.                   value >>= shift[c];
  1082.                   *bp = (png_byte)(value >> 8);
  1083.                   *(bp + 1) = (png_byte)(value & 0xff);
  1084.                }
  1085.             }
  1086.             break;
  1087.          }
  1088.       }
  1089.    }
  1090. }
  1091. #endif
  1092.  
  1093. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1094. /* chop rows of bit depth 16 down to 8 */
  1095. void
  1096. png_do_chop(png_row_infop row_info, png_bytep row)
  1097. {
  1098.    png_bytep sp, dp;
  1099.    png_uint_32 i;
  1100.    if (row && row_info && row_info->bit_depth == 16)
  1101.    {
  1102.       sp = row;
  1103.       dp = row;
  1104.       for (i = 0; i < row_info->width * row_info->channels; i++)
  1105.       {
  1106.          *dp = *sp;
  1107. /* not yet, as I'm afraid of overflow here
  1108.          *dp = ((((((png_uint_16)(*sp) << 8)) |
  1109.             (png_uint_16)((*(sp + 1) - *sp) & 0xff) +
  1110.             0x7f) >> 8) & 0xff);
  1111. */
  1112.          sp += 2;
  1113.          dp++;
  1114.       }
  1115.       row_info->bit_depth = 8;
  1116.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1117.       row_info->rowbytes = row_info->width * row_info->channels;
  1118.    }
  1119. }
  1120. #endif
  1121.  
  1122. #if defined(PNG_READ_FILLER_SUPPORTED)
  1123. /* add filler byte */
  1124. void
  1125. png_do_read_filler(png_row_infop row_info, png_bytep row,
  1126.    png_byte filler, png_byte flags)
  1127. {
  1128.    png_bytep sp, dp;
  1129.    png_uint_32 i;
  1130.    if (row && row_info && row_info->color_type == 2 &&
  1131.       row_info->bit_depth == 8)
  1132.    {
  1133.       if (flags & PNG_FLAG_FILLER_AFTER)
  1134.       {
  1135.          for (i = 1, sp = row + (png_size_t)row_info->width * 3,
  1136.             dp = row + (png_size_t)row_info->width * 4;
  1137.             i < row_info->width;
  1138.             i++)
  1139.          {
  1140.             *(--dp) = filler;
  1141.             *(--dp) = *(--sp);
  1142.             *(--dp) = *(--sp);
  1143.             *(--dp) = *(--sp);
  1144.          }
  1145.          *(--dp) = filler;
  1146.          row_info->channels = 4;
  1147.          row_info->pixel_depth = 32;
  1148.          row_info->rowbytes = row_info->width * 4;
  1149.       }
  1150.       else
  1151.       {
  1152.          for (i = 0, sp = row + (png_size_t)row_info->width * 3,
  1153.             dp = row + (png_size_t)row_info->width * 4;
  1154.             i < row_info->width;
  1155.             i++)
  1156.          {
  1157.             *(--dp) = *(--sp);
  1158.             *(--dp) = *(--sp);
  1159.             *(--dp) = *(--sp);
  1160.             *(--dp) = filler;
  1161.          }
  1162.          row_info->channels = 4;
  1163.          row_info->pixel_depth = 32;
  1164.          row_info->rowbytes = row_info->width * 4;
  1165.       }
  1166.    }
  1167. }
  1168. #endif
  1169.  
  1170. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1171. /* expand grayscale files to rgb, with or without alpha */
  1172. void
  1173. png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  1174. {
  1175.    png_bytep sp, dp;
  1176.    png_uint_32 i;
  1177.  
  1178.    if (row && row_info && row_info->bit_depth >= 8 &&
  1179.       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
  1180.    {
  1181.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1182.       {
  1183.          if (row_info->bit_depth == 8)
  1184.          {
  1185.             for (i = 0, sp = row + (png_size_t)row_info->width - 1,
  1186.                dp = row + (png_size_t)row_info->width * 3 - 1;
  1187.                i < row_info->width;
  1188.                i++)
  1189.             {
  1190.                *(dp--) = *sp;
  1191.                *(dp--) = *sp;
  1192.                *(dp--) = *sp;
  1193.                sp--;
  1194.             }
  1195.          }
  1196.          else
  1197.          {
  1198.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1199.                dp = row + (png_size_t)row_info->width * 6 - 1;
  1200.                i < row_info->width;
  1201.                i++)
  1202.             {
  1203.                *(dp--) = *sp;
  1204.                *(dp--) = *(sp - 1);
  1205.                *(dp--) = *sp;
  1206.                *(dp--) = *(sp - 1);
  1207.                *(dp--) = *sp;
  1208.                *(dp--) = *(sp - 1);
  1209.                sp--;
  1210.                sp--;
  1211.             }
  1212.          }
  1213.       }
  1214.       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1215.       {
  1216.          if (row_info->bit_depth == 8)
  1217.          {
  1218.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1219.                dp = row + (png_size_t)row_info->width * 4 - 1;
  1220.                i < row_info->width;
  1221.                i++)
  1222.             {
  1223.                *(dp--) = *(sp--);
  1224.                *(dp--) = *sp;
  1225.                *(dp--) = *sp;
  1226.                *(dp--) = *sp;
  1227.                sp--;
  1228.             }
  1229.          }
  1230.          else
  1231.          {
  1232.             for (i = 0, sp = row + (png_size_t)row_info->width * 4 - 1,
  1233.                dp = row + (png_size_t)row_info->width * 8 - 1;
  1234.                i < row_info->width;
  1235.                i++)
  1236.             {
  1237.                *(dp--) = *(sp--);
  1238.                *(dp--) = *(sp--);
  1239.                *(dp--) = *sp;
  1240.                *(dp--) = *(sp - 1);
  1241.                *(dp--) = *sp;
  1242.                *(dp--) = *(sp - 1);
  1243.                *(dp--) = *sp;
  1244.                *(dp--) = *(sp - 1);
  1245.                sp--;
  1246.                sp--;
  1247.             }
  1248.          }
  1249.       }
  1250.       row_info->channels += (png_byte)2;
  1251.       row_info->color_type |= PNG_COLOR_MASK_COLOR;
  1252.       row_info->pixel_depth = (png_byte)(row_info->channels *
  1253.          row_info->bit_depth);
  1254.       row_info->rowbytes = ((row_info->width *
  1255.          row_info->pixel_depth + 7) >> 3);
  1256.    }
  1257. }
  1258. #endif
  1259.  
  1260. /* build a grayscale palette.  Palette is assumed to be 1 << bit_depth
  1261.    large of png_color.  This lets grayscale images be treated as
  1262.    paletted.  Most useful for gamma correction and simplification
  1263.    of code. */
  1264. void
  1265. png_build_grayscale_palette(int bit_depth, png_colorp palette)
  1266. {
  1267.    int num_palette;
  1268.    int color_inc;
  1269.    int i;
  1270.    int v;
  1271.  
  1272.    if (!palette)
  1273.       return;
  1274.  
  1275.    switch (bit_depth)
  1276.    {
  1277.       case 1:
  1278.          num_palette = 2;
  1279.          color_inc = 0xff;
  1280.          break;
  1281.       case 2:
  1282.          num_palette = 4;
  1283.          color_inc = 0x55;
  1284.          break;
  1285.       case 4:
  1286.          num_palette = 16;
  1287.          color_inc = 0x11;
  1288.          break;
  1289.       case 8:
  1290.          num_palette = 256;
  1291.          color_inc = 1;
  1292.          break;
  1293.       default:
  1294.          num_palette = 0;
  1295.          color_inc = 0;
  1296.          break;
  1297.    }
  1298.  
  1299.    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
  1300.    {
  1301.       palette[i].red = (png_byte)v;
  1302.       palette[i].green = (png_byte)v;
  1303.       palette[i].blue = (png_byte)v;
  1304.    }
  1305. }
  1306.  
  1307. /* This function is currently unused? */
  1308. #if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_CORRECT_PALETTE_SUPPORTED)
  1309. void
  1310. png_correct_palette(png_structp png_ptr, png_colorp palette,
  1311.    int num_palette)
  1312. {
  1313. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  1314.    if ((png_ptr->transformations & (PNG_GAMMA)) &&
  1315.       (png_ptr->transformations & (PNG_BACKGROUND)))
  1316.    {
  1317.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1318.       {
  1319.          int i;
  1320.          png_color back, back_1;
  1321.  
  1322.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  1323.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  1324.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  1325.  
  1326.          back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  1327.          back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  1328.          back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  1329.  
  1330.          for (i = 0; i < num_palette; i++)
  1331.          {
  1332.             if (i < (int)png_ptr->num_trans &&
  1333.                png_ptr->trans[i] == 0)
  1334.             {
  1335.                palette[i] = back;
  1336.             }
  1337.             else if (i < (int)png_ptr->num_trans &&
  1338.                png_ptr->trans[i] != 0xff)
  1339.             {
  1340.                int v;
  1341.  
  1342.                v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
  1343.                v = (int)(((png_uint_32)(v) *
  1344.                   (png_uint_32)(png_ptr->trans[i]) +
  1345.                   (png_uint_32)(back_1.red) *
  1346.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1347.                   127) / 255);
  1348.                palette[i].red = png_ptr->gamma_from_1[v];
  1349.  
  1350.                v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
  1351.                v = (int)(((png_uint_32)(v) *
  1352.                   (png_uint_32)(png_ptr->trans[i]) +
  1353.                   (png_uint_32)(back_1.green) *
  1354.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1355.                   127) / 255);
  1356.                palette[i].green = png_ptr->gamma_from_1[v];
  1357.  
  1358.                v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
  1359.                v = (int)(((png_uint_32)(v) *
  1360.                   (png_uint_32)(png_ptr->trans[i]) +
  1361.                   (png_uint_32)(back_1.blue) *
  1362.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1363.                   127) / 255);
  1364.                palette[i].blue = png_ptr->gamma_from_1[v];
  1365.             }
  1366.             else
  1367.             {
  1368.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1369.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1370.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1371.             }
  1372.          }
  1373.       }
  1374.       else
  1375.       {
  1376.          int i;
  1377.          png_color back;
  1378.  
  1379.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  1380.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  1381.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  1382.  
  1383.          for (i = 0; i < num_palette; i++)
  1384.          {
  1385.             if (palette[i].red == png_ptr->trans_values.gray)
  1386.             {
  1387.                palette[i] = back;
  1388.             }
  1389.             else
  1390.             {
  1391.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1392.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1393.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1394.             }
  1395.          }
  1396.       }
  1397.    }
  1398.    else
  1399. #endif
  1400. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1401.    if (png_ptr->transformations & (PNG_GAMMA))
  1402.    {
  1403.       int i;
  1404.  
  1405.       for (i = 0; i < num_palette; i++)
  1406.       {
  1407.          palette[i].red = png_ptr->gamma_table[palette[i].red];
  1408.          palette[i].green = png_ptr->gamma_table[palette[i].green];
  1409.          palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1410.       }
  1411.    }
  1412. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1413.    else
  1414. #endif
  1415. #endif
  1416. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1417.    if (png_ptr->transformations & (PNG_BACKGROUND))
  1418.    {
  1419.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1420.       {
  1421.          int i;
  1422.          png_color back;
  1423.  
  1424.          back.red   = (png_byte)png_ptr->background.red;
  1425.          back.green = (png_byte)png_ptr->background.green;
  1426.          back.blue  = (png_byte)png_ptr->background.blue;
  1427.  
  1428.          for (i = 0; i < num_palette; i++)
  1429.          {
  1430.             if (i >= (int)png_ptr->num_trans ||
  1431.                png_ptr->trans[i] == 0)
  1432.             {
  1433.                palette[i].red = back.red;
  1434.                palette[i].green = back.green;
  1435.                palette[i].blue = back.blue;
  1436.             }
  1437.             else if (i < (int)png_ptr->num_trans ||
  1438.                png_ptr->trans[i] != 0xff)
  1439.             {
  1440.                palette[i].red = (png_byte)((
  1441.                   (png_uint_32)(png_ptr->palette[i].red) *
  1442.                   (png_uint_32)(png_ptr->trans[i]) +
  1443.                   (png_uint_32)(back.red) *
  1444.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1445.                   127) / 255);
  1446.                palette[i].green = (png_byte)((
  1447.                   (png_uint_32)(png_ptr->palette[i].green) *
  1448.                   (png_uint_32)(png_ptr->trans[i]) +
  1449.                   (png_uint_32)(back.green) *
  1450.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1451.                   127) / 255);
  1452.                palette[i].blue = (png_byte)((
  1453.                   (png_uint_32)(png_ptr->palette[i].blue) *
  1454.                   (png_uint_32)(png_ptr->trans[i]) +
  1455.                   (png_uint_32)(back.blue) *
  1456.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1457.                   127) / 255);
  1458.             }
  1459.          }
  1460.       }
  1461.       else /* assume grayscale palette (what else could it be?) */
  1462.       {
  1463.          int i;
  1464.  
  1465.          for (i = 0; i < num_palette; i++)
  1466.          {
  1467.             if (i == (int)png_ptr->trans_values.gray)
  1468.             {
  1469.                palette[i].red = (png_byte)png_ptr->background.red;
  1470.                palette[i].green = (png_byte)png_ptr->background.green;
  1471.                palette[i].blue = (png_byte)png_ptr->background.blue;
  1472.             }
  1473.          }
  1474.       }
  1475.    }
  1476. #endif
  1477. }
  1478. #endif
  1479.  
  1480. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1481. /* replace any alpha or transparency with the supplied background color.
  1482.    background is the color.  note that paletted files are taken care of
  1483.    elsewhere */
  1484. void
  1485. png_do_background(png_row_infop row_info, png_bytep row,
  1486.    png_color_16p trans_values, png_color_16p background,
  1487.    png_color_16p background_1,
  1488.    png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
  1489.    png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
  1490.    png_uint_16pp gamma_16_to_1, int gamma_shift)
  1491. {
  1492.    png_bytep sp, dp;
  1493.    png_uint_32 i;
  1494.    int shift;
  1495.  
  1496.    if (row && row_info && background &&
  1497.       (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
  1498.       (row_info->color_type != PNG_COLOR_TYPE_PALETTE &&
  1499.       trans_values)))
  1500.    {
  1501.       switch (row_info->color_type)
  1502.       {
  1503.          case PNG_COLOR_TYPE_GRAY:
  1504.          {
  1505.             switch (row_info->bit_depth)
  1506.             {
  1507.                case 1:
  1508.                {
  1509.                   sp = row;
  1510.                   shift = 7;
  1511.                   for (i = 0; i < row_info->width; i++)
  1512.                   {
  1513.                      if (((*sp >> shift) & 0x1) ==
  1514.                         trans_values->gray)
  1515.                      {
  1516.                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  1517.                         *sp |= (png_byte)(background->gray << shift);
  1518.                      }
  1519.                      if (!shift)
  1520.                      {
  1521.                         shift = 7;
  1522.                         sp++;
  1523.                      }
  1524.                      else
  1525.                         shift--;
  1526.                   }
  1527.                   break;
  1528.                }
  1529.                case 2:
  1530.                {
  1531.                   sp = row;
  1532.                   shift = 6;
  1533.                   for (i = 0; i < row_info->width; i++)
  1534.                   {
  1535.                      if (((*sp >> shift) & 0x3) ==
  1536.                         trans_values->gray)
  1537.                      {
  1538.                         *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  1539.                         *sp |= (png_byte)(background->gray << shift);
  1540.                      }
  1541.                      if (!shift)
  1542.                      {
  1543.                         shift = 6;
  1544.                         sp++;
  1545.                      }
  1546.                      else
  1547.                         shift -= 2;
  1548.                   }
  1549.                   break;
  1550.                }
  1551.                case 4:
  1552.                {
  1553.                   sp = row;
  1554.                   shift = 4;
  1555.                   for (i = 0; i < row_info->width; i++)
  1556.                   {
  1557.                      if (((*sp >> shift) & 0xf) ==
  1558.                         trans_values->gray)
  1559.                      {
  1560.                         *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  1561.                         *sp |= (png_byte)(background->gray << shift);
  1562.                      }
  1563.                      if (!shift)
  1564.                      {
  1565.                         shift = 4;
  1566.                         sp++;
  1567.                      }
  1568.                      else
  1569.                         shift -= 4;
  1570.                   }
  1571.                   break;
  1572.                }
  1573.                case 8:
  1574.                {
  1575. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1576.                   if (gamma_table)
  1577.                   {
  1578.  
  1579.                      for (i = 0, sp = row;
  1580.                         i < row_info->width; i++, sp++)
  1581.                      {
  1582.                         if (*sp == trans_values->gray)
  1583.                         {
  1584.                            *sp = background->gray;
  1585.                         }
  1586.                         else
  1587.                         {
  1588.                            *sp = gamma_table[*sp];
  1589.                         }
  1590.                      }
  1591.                   }
  1592.                   else
  1593. #endif
  1594.                   {
  1595.                      for (i = 0, sp = row;
  1596.                         i < row_info->width; i++, sp++)
  1597.                      {
  1598.                         if (*sp == trans_values->gray)
  1599.                         {
  1600.                            *sp = background->gray;
  1601.                         }
  1602.                      }
  1603.                   }
  1604.                   break;
  1605.                }
  1606.                case 16:
  1607.                {
  1608. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1609.                   if (gamma_16)
  1610.                   {
  1611.                      for (i = 0, sp = row;
  1612.                         i < row_info->width; i++, sp += 2)
  1613.                      {
  1614.                         png_uint_16 v;
  1615.  
  1616.                         v = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1617.                            (png_uint_16)(*(sp + 1)));
  1618.                         if (v == trans_values->gray)
  1619.                         {
  1620.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1621.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1622.                         }
  1623.                         else
  1624.                         {
  1625.                            v = gamma_16[
  1626.                               *(sp + 1) >> gamma_shift][*sp];
  1627.                            *sp = (png_byte)((v >> 8) & 0xff);
  1628.                            *(sp + 1) = (png_byte)(v & 0xff);
  1629.                         }
  1630.                      }
  1631.                   }
  1632.                   else
  1633. #endif
  1634.                   {
  1635.                      for (i = 0, sp = row;
  1636.                         i < row_info->width; i++, sp += 2)
  1637.                      {
  1638.                         png_uint_16 v;
  1639.  
  1640.                         v = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1641.                            (png_uint_16)(*(sp + 1)));
  1642.                         if (v == trans_values->gray)
  1643.                         {
  1644.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1645.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1646.                         }
  1647.                      }
  1648.                   }
  1649.                   break;
  1650.                }
  1651.             }
  1652.             break;
  1653.          }
  1654.          case PNG_COLOR_TYPE_RGB:
  1655.          {
  1656.             if (row_info->bit_depth == 8)
  1657.             {
  1658. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1659.                if (gamma_table)
  1660.                {
  1661.                   for (i = 0, sp = row;
  1662.                      i < row_info->width; i++, sp += 3)
  1663.                   {
  1664.                      if (*sp == trans_values->red &&
  1665.                         *(sp + 1) == trans_values->green &&
  1666.                         *(sp + 2) == trans_values->blue)
  1667.                      {
  1668.                         *sp = background->red;
  1669.                         *(sp + 1) = background->green;
  1670.                         *(sp + 2) = background->blue;
  1671.                      }
  1672.                      else
  1673.                      {
  1674.                         *sp = gamma_table[*sp];
  1675.                         *(sp + 1) = gamma_table[*(sp + 1)];
  1676.                         *(sp + 2) = gamma_table[*(sp + 2)];
  1677.                      }
  1678.                   }
  1679.                }
  1680.                else
  1681. #endif
  1682.                {
  1683.                   for (i = 0, sp = row;
  1684.                      i < row_info->width; i++, sp += 3)
  1685.                   {
  1686.                      if (*sp == trans_values->red &&
  1687.                         *(sp + 1) == trans_values->green &&
  1688.                         *(sp + 2) == trans_values->blue)
  1689.                      {
  1690.                         *sp = background->red;
  1691.                         *(sp + 1) = background->green;
  1692.                         *(sp + 2) = background->blue;
  1693.                      }
  1694.                   }
  1695.                }
  1696.             }
  1697.             else if (row_info->bit_depth == 16)
  1698.             {
  1699. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1700.                if (gamma_16)
  1701.                {
  1702.                   for (i = 0, sp = row;
  1703.                      i < row_info->width; i++, sp += 6)
  1704.                   {
  1705.                      png_uint_16 r, g, b;
  1706.  
  1707.                      r = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1708.                         (png_uint_16)(*(sp + 1)));
  1709.                      g = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1710.                         (png_uint_16)(*(sp + 3)));
  1711.                      b = (png_uint_16)(((png_uint_16)(*(sp + 4)) << 8) +
  1712.                         (png_uint_16)(*(sp + 5)));
  1713.                      if (r == trans_values->red &&
  1714.                         g == trans_values->green &&
  1715.                         b == trans_values->blue)
  1716.                      {
  1717.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  1718.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  1719.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1720.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  1721.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1722.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  1723.                      }
  1724.                      else
  1725.                      {
  1726.                         png_uint_16 v;
  1727.                         v = gamma_16[
  1728.                            *(sp + 1) >> gamma_shift][*sp];
  1729.                         *sp = (png_byte)((v >> 8) & 0xff);
  1730.                         *(sp + 1) = (png_byte)(v & 0xff);
  1731.                         v = gamma_16[
  1732.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  1733.                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
  1734.                         *(sp + 3) = (png_byte)(v & 0xff);
  1735.                         v = gamma_16[
  1736.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  1737.                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
  1738.                         *(sp + 5) = (png_byte)(v & 0xff);
  1739.                      }
  1740.                   }
  1741.                }
  1742.                else
  1743. #endif
  1744.                {
  1745.                   for (i = 0, sp = row;
  1746.                      i < row_info->width; i++, sp += 6)
  1747.                   {
  1748.                      png_uint_16 r, g, b;
  1749.  
  1750.                      r = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1751.                         (png_uint_16)(*(sp + 1)));
  1752.                      g = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1753.                         (png_uint_16)(*(sp + 3)));
  1754.                      b = (png_uint_16)(((png_uint_16)(*(sp + 4)) << 8) +
  1755.                         (png_uint_16)(*(sp + 5)));
  1756.                      if (r == trans_values->red &&
  1757.                         g == trans_values->green &&
  1758.                         b == trans_values->blue)
  1759.                      {
  1760.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  1761.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  1762.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1763.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  1764.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1765.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  1766.                      }
  1767.                   }
  1768.                }
  1769.             }
  1770.             break;
  1771.          }
  1772.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  1773.          {
  1774.             switch (row_info->bit_depth)
  1775.             {
  1776.                case 8:
  1777.                {
  1778. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1779.                   if (gamma_to_1 && gamma_from_1 && gamma_table)
  1780.                   {
  1781.                      for (i = 0, sp = row,
  1782.                         dp = row;
  1783.                         i < row_info->width; i++, sp += 2, dp++)
  1784.                      {
  1785.                         png_uint_16 a;
  1786.  
  1787.                         a = *(sp + 1);
  1788.                         if (a == 0xff)
  1789.                         {
  1790.                            *dp = gamma_table[*sp];
  1791.                         }
  1792.                         else if (a == 0)
  1793.                         {
  1794.                            *dp = background->gray;
  1795.                         }
  1796.                         else
  1797.                         {
  1798.                            png_uint_16 v;
  1799.  
  1800.                            v = gamma_to_1[*sp];
  1801.                            v = (png_uint_16)(((png_uint_16)(v) * a +
  1802.                               (png_uint_16)background_1->gray *
  1803.                               (255 - a) + 127) / 255);
  1804.                            *dp = gamma_from_1[v];
  1805.                         }
  1806.                      }
  1807.                   }
  1808.                   else
  1809. #endif
  1810.                   {
  1811.                      for (i = 0, sp = row,
  1812.                         dp = row;
  1813.                         i < row_info->width; i++, sp += 2, dp++)
  1814.                      {
  1815.                         png_uint_16 a;
  1816.  
  1817.                         a = *(sp + 1);
  1818.                         if (a == 0xff)
  1819.                         {
  1820.                            *dp = *sp;
  1821.                         }
  1822.                         else if (a == 0)
  1823.                         {
  1824.                            *dp = background->gray;
  1825.                         }
  1826.                         else
  1827.                         {
  1828.                            *dp = (png_byte)(((png_uint_16)(*sp) * a +
  1829.                               (png_uint_16)background_1->gray *
  1830.                               (255 - a) + 127) / 255);
  1831.                         }
  1832.                      }
  1833.                   }
  1834.                   break;
  1835.                }
  1836.                case 16:
  1837.                {
  1838. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1839.                   if (gamma_16 && gamma_16_from_1 && gamma_16_to_1)
  1840.                   {
  1841.                      for (i = 0, sp = row,
  1842.                         dp = row;
  1843.                         i < row_info->width; i++, sp += 4, dp += 2)
  1844.                      {
  1845.                         png_uint_16 a;
  1846.  
  1847.                         a = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1848.                            (png_uint_16)(*(sp + 3)));
  1849.                         if (a == (png_uint_16)0xffff)
  1850.                         {
  1851.                            png_uint_32 v;
  1852.  
  1853.                            v = gamma_16[
  1854.                               *(sp + 1) >> gamma_shift][*sp];
  1855.                            *dp = (png_byte)((v >> 8) & 0xff);
  1856.                            *(dp + 1) = (png_byte)(v & 0xff);
  1857.                         }
  1858.                         else if (a == 0)
  1859.                         {
  1860.                            *dp = (png_byte)((background->gray >> 8) & 0xff);
  1861.                            *(dp + 1) = (png_byte)(background->gray & 0xff);
  1862.                         }
  1863.                         else
  1864.                         {
  1865.                            png_uint_32 g, v;
  1866.  
  1867.                            g = gamma_16_to_1[
  1868.                               *(sp + 1) >> gamma_shift][*sp];
  1869.                            v = (g * (png_uint_32)a +
  1870.                               (png_uint_32)background_1->gray *
  1871.                               (png_uint_32)((png_uint_16)65535L - a) +
  1872.                               (png_uint_16)32767) / (png_uint_16)65535L;
  1873.                            v = gamma_16_from_1[(size_t)(
  1874.                               (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1875.                            *dp = (png_byte)((v >> 8) & 0xff);
  1876.                            *(dp + 1) = (png_byte)(v & 0xff);
  1877.                         }
  1878.                      }
  1879.                   }
  1880.                   else
  1881. #endif
  1882.                   {
  1883.                      for (i = 0, sp = row,
  1884.                         dp = row;
  1885.                         i < row_info->width; i++, sp += 4, dp += 2)
  1886.                      {
  1887.                         png_uint_16 a;
  1888.  
  1889.                         a = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1890.                            (png_uint_16)(*(sp + 3)));
  1891.                         if (a == (png_uint_16)0xffff)
  1892.                         {
  1893.                            png_memcpy(dp, sp, 2);
  1894.                         }
  1895.                         else if (a == 0)
  1896.                         {
  1897.                            *dp = (png_byte)((background->gray >> 8) & 0xff);
  1898.                            *(dp + 1) = (png_byte)(background->gray & 0xff);
  1899.                         }
  1900.                         else
  1901.                         {
  1902.                            png_uint_32 g, v;
  1903.  
  1904.                            g = ((png_uint_32)(*sp) << 8) +
  1905.                               (png_uint_32)(*(sp + 1));
  1906.                            v = (g * (png_uint_32)a +
  1907.                               (png_uint_32)background_1->gray *
  1908.                               (png_uint_32)((png_uint_16)65535L - a) +
  1909.                               (png_uint_16)32767) / (png_uint_16)65535L;
  1910.                            *dp = (png_byte)((v >> 8) & 0xff);
  1911.                            *(dp + 1) = (png_byte)(v & 0xff);
  1912.                         }
  1913.                      }
  1914.                   }
  1915.                   break;
  1916.                }
  1917.             }
  1918.             break;
  1919.          }
  1920.          case PNG_COLOR_TYPE_RGB_ALPHA:
  1921.          {
  1922.             if (row_info->bit_depth == 8)
  1923.             {
  1924. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1925.                if (gamma_to_1 && gamma_from_1 && gamma_table)
  1926.                {
  1927.                   for (i = 0, sp = row,
  1928.                      dp = row;
  1929.                      i < row_info->width; i++, sp += 4, dp += 3)
  1930.                   {
  1931.                      png_uint_16 a;
  1932.  
  1933.                      a = *(sp + 3);
  1934.                      if (a == 0xff)
  1935.                      {
  1936.                         *dp = gamma_table[*sp];
  1937.                         *(dp + 1) = gamma_table[*(sp + 1)];
  1938.                         *(dp + 2) = gamma_table[*(sp + 2)];
  1939.                      }
  1940.                      else if (a == 0)
  1941.                      {
  1942.                         *dp = background->red;
  1943.                         *(dp + 1) = background->green;
  1944.                         *(dp + 2) = background->blue;
  1945.                      }
  1946.                      else
  1947.                      {
  1948.                         png_uint_16 v;
  1949.  
  1950.                         v = gamma_to_1[*sp];
  1951.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1952.                            (png_uint_16)background_1->red *
  1953.                            (255 - a) + 127) / 255);
  1954.                         *dp = gamma_from_1[v];
  1955.                         v = gamma_to_1[*(sp + 1)];
  1956.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1957.                            (png_uint_16)background_1->green *
  1958.                            (255 - a) + 127) / 255);
  1959.                         *(dp + 1) = gamma_from_1[v];
  1960.                         v = gamma_to_1[*(sp + 2)];
  1961.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1962.                            (png_uint_16)background_1->blue *
  1963.                            (255 - a) + 127) / 255);
  1964.                         *(dp + 2) = gamma_from_1[v];
  1965.                      }
  1966.                   }
  1967.                }
  1968.                else
  1969. #endif
  1970.                {
  1971.                   for (i = 0, sp = row,
  1972.                      dp = row;
  1973.                      i < row_info->width; i++, sp += 4, dp += 3)
  1974.                   {
  1975.                      png_uint_16 a;
  1976.  
  1977.                      a = *(sp + 3);
  1978.                      if (a == 0xff)
  1979.                      {
  1980.                         *dp = *sp;
  1981.                         *(dp + 1) = *(sp + 1);
  1982.                         *(dp + 2) = *(sp + 2);
  1983.                      }
  1984.                      else if (a == 0)
  1985.                      {
  1986.                         *dp = background->red;
  1987.                         *(dp + 1) = background->green;
  1988.                         *(dp + 2) = background->blue;
  1989.                      }
  1990.                      else
  1991.                      {
  1992.                         *dp = (png_byte)(((png_uint_16)(*sp) * a +
  1993.                            (png_uint_16)background->red *
  1994.                            (255 - a) + 127) / 255);
  1995.                         *(dp + 1) = (png_byte)(((png_uint_16)(*(sp + 1)) * a +
  1996.                            (png_uint_16)background->green *
  1997.                            (255 - a) + 127) / 255);
  1998.                         *(dp + 2) = (png_byte)(((png_uint_16)(*(sp + 2)) * a +
  1999.                            (png_uint_16)background->blue *
  2000.                            (255 - a) + 127) / 255);
  2001.                      }
  2002.                   }
  2003.                }
  2004.             }
  2005.             else if (row_info->bit_depth == 16)
  2006.             {
  2007. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2008.                if (gamma_16 && gamma_16_from_1 && gamma_16_to_1)
  2009.                {
  2010.                   for (i = 0, sp = row,
  2011.                      dp = row;
  2012.                      i < row_info->width; i++, sp += 8, dp += 6)
  2013.                   {
  2014.                      png_uint_16 a;
  2015.  
  2016.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  2017.                         (png_uint_16)(*(sp + 7)));
  2018.                      if (a == (png_uint_16)0xffff)
  2019.                      {
  2020.                         png_uint_16 v;
  2021.  
  2022.                         v = gamma_16[
  2023.                            *(sp + 1) >> gamma_shift][*sp];
  2024.                         *dp = (png_byte)((v >> 8) & 0xff);
  2025.                         *(dp + 1) = (png_byte)(v & 0xff);
  2026.                         v = gamma_16[
  2027.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  2028.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  2029.                         *(dp + 3) = (png_byte)(v & 0xff);
  2030.                         v = gamma_16[
  2031.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  2032.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  2033.                         *(dp + 5) = (png_byte)(v & 0xff);
  2034.                      }
  2035.                      else if (a == 0)
  2036.                      {
  2037.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  2038.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  2039.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2040.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  2041.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2042.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  2043.                      }
  2044.                      else
  2045.                      {
  2046.                         png_uint_32 v;
  2047.  
  2048.                         v = gamma_16_to_1[
  2049.                            *(sp + 1) >> gamma_shift][*sp];
  2050.                         v = (v * (png_uint_32)a +
  2051.                            (png_uint_32)background->red *
  2052.                            (png_uint_32)((png_uint_16)65535L - a) +
  2053.                            (png_uint_16)32767) / (png_uint_16)65535L;
  2054.                         v = gamma_16_from_1[(size_t)(
  2055.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  2056.                         *dp = (png_byte)((v >> 8) & 0xff);
  2057.                         *(dp + 1) = (png_byte)(v & 0xff);
  2058.                         v = gamma_16_to_1[
  2059.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  2060.                         v = (v * (png_uint_32)a +
  2061.                            (png_uint_32)background->green *
  2062.                            (png_uint_32)((png_uint_16)65535L - a) +
  2063.                            (png_uint_16)32767) / (png_uint_16)65535L;
  2064.                         v = gamma_16_from_1[(size_t)(
  2065.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  2066.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  2067.                         *(dp + 3) = (png_byte)(v & 0xff);
  2068.                         v = gamma_16_to_1[
  2069.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  2070.                         v = (v * (png_uint_32)a +
  2071.                            (png_uint_32)background->blue *
  2072.                            (png_uint_32)((png_uint_16)65535L - a) +
  2073.                            (png_uint_16)32767) / (png_uint_16)65535L;
  2074.                         v = gamma_16_from_1[(size_t)(
  2075.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  2076.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  2077.                         *(dp + 5) = (png_byte)(v & 0xff);
  2078.                      }
  2079.                   }
  2080.                }
  2081.                else
  2082. #endif
  2083.                {
  2084.                   for (i = 0, sp = row,
  2085.                      dp = row;
  2086.                      i < row_info->width; i++, sp += 8, dp += 6)
  2087.                   {
  2088.                      png_uint_16 a;
  2089.  
  2090.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  2091.                         (png_uint_16)(*(sp + 7)));
  2092.                      if (a == (png_uint_16)0xffff)
  2093.                      {
  2094.                         png_memcpy(dp, sp, 6);
  2095.                      }
  2096.                      else if (a == 0)
  2097.                      {
  2098.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  2099.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  2100.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2101.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  2102.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2103.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  2104.                      }
  2105.                      else
  2106.                      {
  2107.                         png_uint_32 r, g, b, v;
  2108.  
  2109.                         r = ((png_uint_32)(*sp) << 8) +
  2110.                            (png_uint_32)(*(sp + 1));
  2111.                         g = ((png_uint_32)(*(sp + 2)) << 8) +
  2112.                            (png_uint_32)(*(sp + 3));
  2113.                         b = ((png_uint_32)(*(sp + 4)) << 8) +
  2114.                            (png_uint_32)(*(sp + 5));
  2115.                         v = (r * (png_uint_32)a +
  2116.                            (png_uint_32)background->red *
  2117.                            (png_uint_32)((png_uint_32)65535L - a) +
  2118.                            (png_uint_32)32767) / (png_uint_32)65535L;
  2119.                         *dp = (png_byte)((v >> 8) & 0xff);
  2120.                         *(dp + 1) = (png_byte)(v & 0xff);
  2121.                         v = (g * (png_uint_32)a +
  2122.                            (png_uint_32)background->green *
  2123.                            (png_uint_32)((png_uint_32)65535L - a) +
  2124.                            (png_uint_32)32767) / (png_uint_32)65535L;
  2125.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  2126.                         *(dp + 3) = (png_byte)(v & 0xff);
  2127.                         v = (b * (png_uint_32)a +
  2128.                            (png_uint_32)background->blue *
  2129.                            (png_uint_32)((png_uint_32)65535L - a) +
  2130.                            (png_uint_32)32767) / (png_uint_32)65535L;
  2131.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  2132.                         *(dp + 5) = (png_byte)(v & 0xff);
  2133.                      }
  2134.                   }
  2135.                }
  2136.             }
  2137.             break;
  2138.          }
  2139.       }
  2140.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  2141.       {
  2142.          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
  2143.          row_info->channels--;
  2144.          row_info->pixel_depth = (png_byte)(row_info->channels *
  2145.             row_info->bit_depth);
  2146.          row_info->rowbytes = ((row_info->width *
  2147.             row_info->pixel_depth + 7) >> 3);
  2148.       }
  2149.    }
  2150. }
  2151. #endif
  2152.  
  2153. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2154. /* gamma correct the image, avoiding the alpha channel.  Make sure
  2155.    you do this after you deal with the trasparency issue on grayscale
  2156.    or rgb images. If your bit depth is 8, use gamma_table, if it is 16,
  2157.    use gamma_16_table and gamma_shift.  Build these with
  2158.    build_gamma_table().  If your bit depth <= 8, gamma correct a
  2159.    palette, not the data.  */
  2160. void
  2161. png_do_gamma(png_row_infop row_info, png_bytep row,
  2162.    png_bytep gamma_table, png_uint_16pp gamma_16_table,
  2163.    int gamma_shift)
  2164. {
  2165.    png_bytep sp;
  2166.    png_uint_32 i;
  2167.  
  2168.    if (row && row_info && ((row_info->bit_depth <= 8 && gamma_table) ||
  2169.       (row_info->bit_depth == 16 && gamma_16_table)))
  2170.    {
  2171.       switch (row_info->color_type)
  2172.       {
  2173.          case PNG_COLOR_TYPE_RGB:
  2174.          {
  2175.             if (row_info->bit_depth == 8)
  2176.             {
  2177.                for (i = 0, sp = row;
  2178.                   i < row_info->width; i++)
  2179.                {
  2180.                   *sp = gamma_table[*sp];
  2181.                   sp++;
  2182.                   *sp = gamma_table[*sp];
  2183.                   sp++;
  2184.                   *sp = gamma_table[*sp];
  2185.                   sp++;
  2186.                }
  2187.             }
  2188.             else if (row_info->bit_depth == 16)
  2189.             {
  2190.                for (i = 0, sp = row;
  2191.                   i < row_info->width; i++)
  2192.                {
  2193.                   png_uint_16 v;
  2194.  
  2195.                   v = gamma_16_table[*(sp + 1) >>
  2196.                      gamma_shift][*sp];
  2197.                   *sp = (png_byte)((v >> 8) & 0xff);
  2198.                   *(sp + 1) = (png_byte)(v & 0xff);
  2199.                   sp += 2;
  2200.                   v = gamma_16_table[*(sp + 1) >>
  2201.                      gamma_shift][*sp];
  2202.                   *sp = (png_byte)((v >> 8) & 0xff);
  2203.                   *(sp + 1) = (png_byte)(v & 0xff);
  2204.                   sp += 2;
  2205.                   v = gamma_16_table[*(sp + 1) >>
  2206.                      gamma_shift][*sp];
  2207.                   *sp = (png_byte)((v >> 8) & 0xff);
  2208.                   *(sp + 1) = (png_byte)(v & 0xff);
  2209.                   sp += 2;
  2210.                }
  2211.             }
  2212.             break;
  2213.          }
  2214.          case PNG_COLOR_TYPE_RGB_ALPHA:
  2215.          {
  2216.             if (row_info->bit_depth == 8)
  2217.             {
  2218.                for (i = 0, sp = row;
  2219.                   i < row_info->width; i++)
  2220.                {
  2221.                   *sp = gamma_table[*sp];
  2222.                   sp++;
  2223.                   *sp = gamma_table[*sp];
  2224.                   sp++;
  2225.                   *sp = gamma_table[*sp];
  2226.                   sp++;
  2227.                   sp++;
  2228.                }
  2229.             }
  2230.             else if (row_info->bit_depth == 16)
  2231.             {
  2232.                for (i = 0, sp = row;
  2233.                   i < row_info->width; i++)
  2234.                {
  2235.                   png_uint_16 v;
  2236.  
  2237.                   v = gamma_16_table[*(sp + 1) >>
  2238.                      gamma_shift][*sp];
  2239.                   *sp = (png_byte)((v >> 8) & 0xff);
  2240.                   *(sp + 1) = (png_byte)(v & 0xff);
  2241.                   sp += 2;
  2242.                   v = gamma_16_table[*(sp + 1) >>
  2243.                      gamma_shift][*sp];
  2244.                   *sp = (png_byte)((v >> 8) & 0xff);
  2245.                   *(sp + 1) = (png_byte)(v & 0xff);
  2246.                   sp += 2;
  2247.                   v = gamma_16_table[*(sp + 1) >>
  2248.                      gamma_shift][*sp];
  2249.                   *sp = (png_byte)((v >> 8) & 0xff);
  2250.                   *(sp + 1) = (png_byte)(v & 0xff);
  2251.                   sp += 4;
  2252.                }
  2253.             }
  2254.             break;
  2255.          }
  2256.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  2257.          {
  2258.             if (row_info->bit_depth == 8)
  2259.             {
  2260.                for (i = 0, sp = row;
  2261.                   i < row_info->width; i++)
  2262.                {
  2263.                   *sp = gamma_table[*sp];
  2264.                   sp++;
  2265.                   sp++;
  2266.                }
  2267.             }
  2268.             else if (row_info->bit_depth == 16)
  2269.             {
  2270.                for (i = 0, sp = row;
  2271.                   i < row_info->width; i++)
  2272.                {
  2273.                   png_uint_16 v;
  2274.  
  2275.                   v = gamma_16_table[*(sp + 1) >>
  2276.                      gamma_shift][*sp];
  2277.                   *sp = (png_byte)((v >> 8) & 0xff);
  2278.                   *(sp + 1) = (png_byte)(v & 0xff);
  2279.                   sp += 4;
  2280.                }
  2281.             }
  2282.             break;
  2283.          }
  2284.          case PNG_COLOR_TYPE_GRAY:
  2285.          {
  2286.             if (row_info->bit_depth == 8)
  2287.             {
  2288.                for (i = 0, sp = row;
  2289.                   i < row_info->width; i++)
  2290.                {
  2291.                   *sp = gamma_table[*sp];
  2292.                   sp++;
  2293.                }
  2294.             }
  2295.             else if (row_info->bit_depth == 16)
  2296.             {
  2297.                for (i = 0, sp = row;
  2298.                   i < row_info->width; i++)
  2299.                {
  2300.                   png_uint_16 v;
  2301.  
  2302.                   v = gamma_16_table[*(sp + 1) >>
  2303.                      gamma_shift][*sp];
  2304.                   *sp = (png_byte)((v >> 8) & 0xff);
  2305.                   *(sp + 1) = (png_byte)(v & 0xff);
  2306.                   sp += 2;
  2307.                }
  2308.             }
  2309.             break;
  2310.          }
  2311.       }
  2312.    }
  2313. }
  2314. #endif
  2315.  
  2316. #if defined(PNG_READ_EXPAND_SUPPORTED)
  2317. /* expands a palette row to an rgb or rgba row depending
  2318.    upon whether you supply trans and num_trans */
  2319. void
  2320. png_do_expand_palette(png_row_infop row_info, png_bytep row,
  2321.    png_colorp palette,
  2322.    png_bytep trans, int num_trans)
  2323. {
  2324.    int shift, value;
  2325.    png_bytep sp, dp;
  2326.    png_uint_32 i;
  2327.  
  2328.    if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_PALETTE)
  2329.    {
  2330.       if (row_info->bit_depth < 8)
  2331.       {
  2332.          switch (row_info->bit_depth)
  2333.          {
  2334.             case 1:
  2335.             {
  2336.                sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2337.                dp = row + (png_size_t)row_info->width - 1;
  2338.                shift = 7 - (int)((row_info->width + 7) & 7);
  2339.                for (i = 0; i < row_info->width; i++)
  2340.                {
  2341.                   if ((*sp >> shift) & 0x1)
  2342.                      *dp = 1;
  2343.                   else
  2344.                      *dp = 0;
  2345.                   if (shift == 7)
  2346.                   {
  2347.                      shift = 0;
  2348.                      sp--;
  2349.                   }
  2350.                   else
  2351.                      shift++;
  2352.  
  2353.                   dp--;
  2354.                }
  2355.                break;
  2356.             }
  2357.             case 2:
  2358.             {
  2359.                sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2360.                dp = row + (png_size_t)row_info->width - 1;
  2361.                shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2362.                for (i = 0; i < row_info->width; i++)
  2363.                {
  2364.                   value = (*sp >> shift) & 0x3;
  2365.                   *dp = (png_byte)value;
  2366.                   if (shift == 6)
  2367.                   {
  2368.                      shift = 0;
  2369.                      sp--;
  2370.                   }
  2371.                   else
  2372.                      shift += 2;
  2373.  
  2374.                   dp--;
  2375.                }
  2376.                break;
  2377.             }
  2378.             case 4:
  2379.             {
  2380.                sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2381.                dp = row + (png_size_t)row_info->width - 1;
  2382.                shift = (int)((row_info->width & 1) << 2);
  2383.                for (i = 0; i < row_info->width; i++)
  2384.                {
  2385.                   value = (*sp >> shift) & 0xf;
  2386.                   *dp = (png_byte)value;
  2387.                   if (shift == 4)
  2388.                   {
  2389.                      shift = 0;
  2390.                      sp--;
  2391.                   }
  2392.                   else
  2393.                      shift += 4;
  2394.  
  2395.                   dp--;
  2396.                }
  2397.                break;
  2398.             }
  2399.          }
  2400.          row_info->bit_depth = 8;
  2401.          row_info->pixel_depth = 8;
  2402.          row_info->rowbytes = row_info->width;
  2403.       }
  2404.       switch (row_info->bit_depth)
  2405.       {
  2406.          case 8:
  2407.          {
  2408.             if (trans)
  2409.             {
  2410.                sp = row + (png_size_t)row_info->width - 1;
  2411.                dp = row + (png_size_t)(row_info->width << 2) - 1;
  2412.  
  2413.                for (i = 0; i < row_info->width; i++)
  2414.                {
  2415.                   if (*sp >= (png_byte)num_trans)
  2416.                      *dp-- = 0xff;
  2417.                   else
  2418.                      *dp-- = trans[*sp];
  2419.                   *dp-- = palette[*sp].blue;
  2420.                   *dp-- = palette[*sp].green;
  2421.                   *dp-- = palette[*sp].red;
  2422.                   sp--;
  2423.                }
  2424.                row_info->bit_depth = 8;
  2425.                row_info->pixel_depth = 32;
  2426.                row_info->rowbytes = row_info->width * 4;
  2427.                row_info->color_type = 6;
  2428.                row_info->channels = 4;
  2429.             }
  2430.             else
  2431.             {
  2432.                sp = row + (png_size_t)row_info->width - 1;
  2433.                dp = row + (png_size_t)(row_info->width * 3) - 1;
  2434.  
  2435.                for (i = 0; i < row_info->width; i++)
  2436.                {
  2437.                   *dp-- = palette[*sp].blue;
  2438.                   *dp-- = palette[*sp].green;
  2439.                   *dp-- = palette[*sp].red;
  2440.                   sp--;
  2441.                }
  2442.                row_info->bit_depth = 8;
  2443.                row_info->pixel_depth = 24;
  2444.                row_info->rowbytes = row_info->width * 3;
  2445.                row_info->color_type = 2;
  2446.                row_info->channels = 3;
  2447.             }
  2448.             break;
  2449.          }
  2450.       }
  2451.    }
  2452. }
  2453.  
  2454. /* if the bit depth < 8, it is expanded to 8.  Also, if the
  2455.    transparency value is supplied, an alpha channel is built. */
  2456. void
  2457. png_do_expand(png_row_infop row_info, png_bytep row,
  2458.    png_color_16p trans_value)
  2459. {
  2460.    int shift, value;
  2461.    png_bytep sp, dp;
  2462.    png_uint_32 i;
  2463.  
  2464.    if (row && row_info)
  2465.    {
  2466.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY &&
  2467.          row_info->bit_depth < 8)
  2468.       {
  2469.          switch (row_info->bit_depth)
  2470.          {
  2471.             case 1:
  2472.             {
  2473.                sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2474.                dp = row + (png_size_t)row_info->width - 1;
  2475.                shift = 7 - (int)((row_info->width + 7) & 7);
  2476.                for (i = 0; i < row_info->width; i++)
  2477.                {
  2478.                   if ((*sp >> shift) & 0x1)
  2479.                      *dp = 0xff;
  2480.                   else
  2481.                      *dp = 0;
  2482.                   if (shift == 7)
  2483.                   {
  2484.                      shift = 0;
  2485.                      sp--;
  2486.                   }
  2487.                   else
  2488.                      shift++;
  2489.  
  2490.                   dp--;
  2491.                }
  2492.                break;
  2493.             }
  2494.             case 2:
  2495.             {
  2496.                sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2497.                dp = row + (png_size_t)row_info->width - 1;
  2498.                shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2499.                for (i = 0; i < row_info->width; i++)
  2500.                {
  2501.                   value = (*sp >> shift) & 0x3;
  2502.                   *dp = (png_byte)(value | (value << 2) | (value << 4) |
  2503.                      (value << 6));
  2504.                   if (shift == 6)
  2505.                   {
  2506.                      shift = 0;
  2507.                      sp--;
  2508.                   }
  2509.                   else
  2510.                      shift += 2;
  2511.  
  2512.                   dp--;
  2513.                }
  2514.                break;
  2515.             }
  2516.             case 4:
  2517.             {
  2518.                sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2519.                dp = row + (png_size_t)row_info->width - 1;
  2520.                shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  2521.                for (i = 0; i < row_info->width; i++)
  2522.                {
  2523.                   value = (*sp >> shift) & 0xf;
  2524.                   *dp = (png_byte)(value | (value << 4));
  2525.                   if (shift == 4)
  2526.                   {
  2527.                      shift = 0;
  2528.                      sp--;
  2529.                   }
  2530.                   else
  2531.                      shift = 4;
  2532.  
  2533.                   dp--;
  2534.                }
  2535.                break;
  2536.             }
  2537.          }
  2538.          row_info->bit_depth = 8;
  2539.          row_info->pixel_depth = 8;
  2540.          row_info->rowbytes = row_info->width;
  2541.       }
  2542.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY && trans_value)
  2543.       {
  2544.          if (row_info->bit_depth == 8)
  2545.          {
  2546.             sp = row + (png_size_t)row_info->width - 1;
  2547.             dp = row + (png_size_t)(row_info->width << 1) - 1;
  2548.             for (i = 0; i < row_info->width; i++)
  2549.             {
  2550.                if (*sp == trans_value->gray)
  2551.                   *dp-- = 0;
  2552.                else
  2553.                   *dp-- = 0xff;
  2554.                *dp-- = *sp--;
  2555.             }
  2556.          }
  2557.          else if (row_info->bit_depth == 16)
  2558.          {
  2559.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2560.             dp = row + (png_size_t)(row_info->rowbytes << 1) - 1;
  2561.             for (i = 0; i < row_info->width; i++)
  2562.             {
  2563.                if (((png_uint_16)*(sp) |
  2564.                   ((png_uint_16)*(sp - 1) << 8)) == trans_value->gray)
  2565.                {
  2566.                   *dp-- = 0;
  2567.                   *dp-- = 0;
  2568.                }
  2569.                else
  2570.                {
  2571.                   *dp-- = 0xff;
  2572.                   *dp-- = 0xff;
  2573.                }
  2574.                *dp-- = *sp--;
  2575.                *dp-- = *sp--;
  2576.             }
  2577.          }
  2578.          row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  2579.          row_info->channels = 2;
  2580.          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
  2581.          row_info->rowbytes =
  2582.             ((row_info->width * row_info->pixel_depth) >> 3);
  2583.       }
  2584.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
  2585.       {
  2586.          if (row_info->bit_depth == 8)
  2587.          {
  2588.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2589.             dp = row + (png_size_t)(row_info->width << 2) - 1;
  2590.             for (i = 0; i < row_info->width; i++)
  2591.             {
  2592.                if (*(sp - 2) == trans_value->red &&
  2593.                   *(sp - 1) == trans_value->green &&
  2594.                   *(sp - 0) == trans_value->blue)
  2595.                   *dp-- = 0;
  2596.                else
  2597.                   *dp-- = 0xff;
  2598.                *dp-- = *sp--;
  2599.                *dp-- = *sp--;
  2600.                *dp-- = *sp--;
  2601.             }
  2602.          }
  2603.          else if (row_info->bit_depth == 16)
  2604.          {
  2605.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2606.             dp = row + (png_size_t)(row_info->width << 3) - 1;
  2607.             for (i = 0; i < row_info->width; i++)
  2608.             {
  2609.                if ((((png_uint_16)*(sp - 4) |
  2610.                   ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
  2611.                   (((png_uint_16)*(sp - 2) |
  2612.                   ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
  2613.                   (((png_uint_16)*(sp - 0) |
  2614.                   ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
  2615.                {
  2616.                   *dp-- = 0;
  2617.                   *dp-- = 0;
  2618.                }
  2619.                else
  2620.                {
  2621.                   *dp-- = 0xff;
  2622.                   *dp-- = 0xff;
  2623.                }
  2624.                *dp-- = *sp--;
  2625.                *dp-- = *sp--;
  2626.                *dp-- = *sp--;
  2627.                *dp-- = *sp--;
  2628.                *dp-- = *sp--;
  2629.                *dp-- = *sp--;
  2630.             }
  2631.          }
  2632.          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  2633.          row_info->channels = 4;
  2634.          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
  2635.          row_info->rowbytes =
  2636.             ((row_info->width * row_info->pixel_depth) >> 3);
  2637.       }
  2638.    }
  2639. }
  2640. #endif
  2641.  
  2642. #if defined(PNG_READ_DITHER_SUPPORTED)
  2643. void
  2644. png_do_dither(png_row_infop row_info, png_bytep row,
  2645.     png_bytep palette_lookup, png_bytep dither_lookup)
  2646. {
  2647.    png_bytep sp, dp;
  2648.    png_uint_32 i;
  2649.  
  2650.    if (row && row_info)
  2651.    {
  2652.       if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
  2653.          palette_lookup && row_info->bit_depth == 8)
  2654.       {
  2655.          int r, g, b, p;
  2656.          sp = row;
  2657.          dp = row;
  2658.          for (i = 0; i < row_info->width; i++)
  2659.          {
  2660.             r = *sp++;
  2661.             g = *sp++;
  2662.             b = *sp++;
  2663.  
  2664.             /* this looks real messy, but the compiler will reduce
  2665.                it down to a reasonable formula.  For example, with
  2666.                5 bits per color, we get:
  2667.                p = (((r >> 3) & 0x1f) << 10) |
  2668.                   (((g >> 3) & 0x1f) << 5) |
  2669.                   ((b >> 3) & 0x1f);
  2670.                */
  2671.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2672.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2673.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2674.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2675.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2676.                (PNG_DITHER_BLUE_BITS)) |
  2677.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2678.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2679.  
  2680.             *dp++ = palette_lookup[p];
  2681.          }
  2682.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2683.          row_info->channels = 1;
  2684.          row_info->pixel_depth = row_info->bit_depth;
  2685.          row_info->rowbytes =
  2686.             ((row_info->width * row_info->pixel_depth + 7) >> 3);
  2687.       }
  2688.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
  2689.          palette_lookup && row_info->bit_depth == 8)
  2690.       {
  2691.          int r, g, b, p;
  2692.          sp = row;
  2693.          dp = row;
  2694.          for (i = 0; i < row_info->width; i++)
  2695.          {
  2696.             r = *sp++;
  2697.             g = *sp++;
  2698.             b = *sp++;
  2699.             sp++;
  2700.  
  2701.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2702.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2703.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2704.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2705.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2706.                (PNG_DITHER_BLUE_BITS)) |
  2707.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2708.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2709.  
  2710.             *dp++ = palette_lookup[p];
  2711.          }
  2712.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2713.          row_info->channels = 1;
  2714.          row_info->pixel_depth = row_info->bit_depth;
  2715.          row_info->rowbytes =
  2716.             ((row_info->width * row_info->pixel_depth + 7) >> 3);
  2717.       }
  2718.       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
  2719.          dither_lookup && row_info->bit_depth == 8)
  2720.       {
  2721.          sp = row;
  2722.          for (i = 0; i < row_info->width; i++, sp++)
  2723.          {
  2724.             *sp = dither_lookup[*sp];
  2725.          }
  2726.       }
  2727.    }
  2728. }
  2729. #endif
  2730.  
  2731. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2732. static int png_gamma_shift[] =
  2733.    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
  2734.  
  2735. void
  2736. png_build_gamma_table(png_structp png_ptr)
  2737. {
  2738.    if (png_ptr->bit_depth <= 8)
  2739.    {
  2740.       int i;
  2741.       double g;
  2742.  
  2743.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  2744.  
  2745.       png_ptr->gamma_table = (png_bytep)png_large_malloc(png_ptr,
  2746.          (png_uint_32)256);
  2747.  
  2748.       for (i = 0; i < 256; i++)
  2749.       {
  2750.          png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
  2751.             g) * 255.0 + .5);
  2752.       }
  2753.  
  2754.       if (png_ptr->transformations & PNG_BACKGROUND)
  2755.       {
  2756.          g = 1.0 / (png_ptr->gamma);
  2757.  
  2758.          png_ptr->gamma_to_1 = (png_bytep)png_large_malloc(png_ptr,
  2759.             (png_uint_32)256);
  2760.  
  2761.          for (i = 0; i < 256; i++)
  2762.          {
  2763.             png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
  2764.                g) * 255.0 + .5);
  2765.          }
  2766.  
  2767.          g = 1.0 / (png_ptr->display_gamma);
  2768.  
  2769.          png_ptr->gamma_from_1 = (png_bytep)png_large_malloc(png_ptr,
  2770.             (png_uint_32)256);
  2771.  
  2772.          for (i = 0; i < 256; i++)
  2773.          {
  2774.             png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
  2775.                g) * 255.0 + .5);
  2776.          }
  2777.       }
  2778.    }
  2779.    else
  2780.    {
  2781.       double g;
  2782.       int i, j, shift, num;
  2783.       int sig_bit;
  2784.       png_uint_32 ig;
  2785.  
  2786.       if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  2787.       {
  2788.          sig_bit = (int)png_ptr->sig_bit.red;
  2789.          if ((int)png_ptr->sig_bit.green > sig_bit)
  2790.             sig_bit = png_ptr->sig_bit.green;
  2791.          if ((int)png_ptr->sig_bit.blue > sig_bit)
  2792.             sig_bit = png_ptr->sig_bit.blue;
  2793.       }
  2794.       else
  2795.       {
  2796.          sig_bit = (int)png_ptr->sig_bit.gray;
  2797.       }
  2798.  
  2799.       if (sig_bit > 0)
  2800.          shift = 16 - sig_bit;
  2801.       else
  2802.          shift = 0;
  2803.  
  2804.       if (png_ptr->transformations & PNG_16_TO_8)
  2805.       {
  2806.          if (shift < (16 - PNG_MAX_GAMMA_8))
  2807.             shift = (16 - PNG_MAX_GAMMA_8);
  2808.       }
  2809.  
  2810.       if (shift > 8)
  2811.          shift = 8;
  2812.       if (shift < 0)
  2813.          shift = 0;
  2814.  
  2815.       png_ptr->gamma_shift = (png_byte)shift;
  2816.  
  2817.       num = (1 << (8 - shift));
  2818.  
  2819.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  2820.  
  2821.       png_ptr->gamma_16_table = (png_uint_16pp)png_large_malloc(png_ptr,
  2822.          num * sizeof (png_uint_16p ));
  2823.  
  2824.       if ((png_ptr->transformations & PNG_16_TO_8) &&
  2825.          !(png_ptr->transformations & PNG_BACKGROUND))
  2826.       {
  2827.          double fin, fout;
  2828.          png_uint_32 last, max;
  2829.  
  2830.          for (i = 0; i < num; i++)
  2831.          {
  2832.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2833.                256 * sizeof (png_uint_16));
  2834.          }
  2835.  
  2836.          g = 1.0 / g;
  2837.          last = 0;
  2838.          for (i = 0; i < 256; i++)
  2839.          {
  2840.             fout = ((double)i + 0.5) / 256.0;
  2841.             fin = pow(fout, g);
  2842.             max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
  2843.             while (last <= max)
  2844.             {
  2845.                png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  2846.                   [(int)(last >> (8 - shift))] = (png_uint_16)(
  2847.                   (png_uint_16)i | ((png_uint_16)i << 8));
  2848.                last++;
  2849.             }
  2850.          }
  2851.          while (last < ((png_uint_32)num << 8))
  2852.          {
  2853.             png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  2854.                [(int)(last >> (8 - shift))] =
  2855.                (png_uint_16)65535L;
  2856.             last++;
  2857.          }
  2858.       }
  2859.       else
  2860.       {
  2861.          for (i = 0; i < num; i++)
  2862.          {
  2863.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2864.                256 * sizeof (png_uint_16));
  2865.  
  2866.             ig = (((png_uint_32)i *
  2867.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2868.             for (j = 0; j < 256; j++)
  2869.             {
  2870.                png_ptr->gamma_16_table[i][j] =
  2871.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2872.                      65535.0, g) * 65535.0 + .5);
  2873.             }
  2874.          }
  2875.       }
  2876.  
  2877.       if (png_ptr->transformations & PNG_BACKGROUND)
  2878.       {
  2879.          g = 1.0 / (png_ptr->gamma);
  2880.  
  2881.          png_ptr->gamma_16_to_1 = (png_uint_16pp)png_large_malloc(png_ptr,
  2882.             num * sizeof (png_uint_16p ));
  2883.  
  2884.          for (i = 0; i < num; i++)
  2885.          {
  2886.             png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2887.                256 * sizeof (png_uint_16));
  2888.  
  2889.             ig = (((png_uint_32)i *
  2890.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2891.             for (j = 0; j < 256; j++)
  2892.             {
  2893.                png_ptr->gamma_16_to_1[i][j] =
  2894.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2895.                      65535.0, g) * 65535.0 + .5);
  2896.             }
  2897.          }
  2898.          g = 1.0 / (png_ptr->display_gamma);
  2899.  
  2900.          png_ptr->gamma_16_from_1 = (png_uint_16pp)png_large_malloc(png_ptr,
  2901.             num * sizeof (png_uint_16p));
  2902.  
  2903.          for (i = 0; i < num; i++)
  2904.          {
  2905.             png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2906.                256 * sizeof (png_uint_16));
  2907.  
  2908.             ig = (((png_uint_32)i *
  2909.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2910.             for (j = 0; j < 256; j++)
  2911.             {
  2912.                png_ptr->gamma_16_from_1[i][j] =
  2913.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2914.                      65535.0, g) * 65535.0 + .5);
  2915.             }
  2916.          }
  2917.       }
  2918.    }
  2919. }
  2920. #endif
  2921.  
  2922.